<?php

/**
 * Представляет массив в виде XML-таблицы
 */
class Array2XML implements iArray2XML {
	
	private
		$data = array (),
		$tagName = '';
	
	/**
	 * Конструктор
	 * @param sting $tagName название корневого элемента, относительно которого будет построено дерево
	 * @param array $data
	 */
	public function __construct ($tagName, array $data) {
		$this->tagName = $tagName;
		$this->data = $data;
	}
	
	/**
	 * Возвращает XML-таблицу
	 * @param DOMDocument $xml
	 * @return DOMElement
	 */
	public function __toXML (DOMDocument $xml) {
		$parentNode = $xml->createElement ($this->tagName);
		
		$this->renderData ($xml, $parentNode, $this->data);
		
		return $parentNode;
	}
	
	/**
	 * Возвращает текст XML-таблицы, построенной на основе массива
	 * @return string
	 */
	public function __toString () {
		header ("Content-type: text/xml; charset=utf-8");
		
		$xml = new DOMDocument ('1.0', 'utf-8');
		
		$xml->appendChild ($this->__toXML ($xml));
		
		return $xml->saveXML ();
	}
		
	private function renderData (DOMDocument $xml, DOMElement $parentNode, array $data) {
		foreach ($data as $key => $value) {
			if (is_numeric ($key)) {
				if (is_array ($value)) {
					$this->renderData ($xml, $parentNode, $value);
				} else {
					$parentNode->appendChild ($xml->createElement ('value', (string) $value));
				}
			} else {
				
				$aKParts = explode (':', $key);
				
				if (count ($aKParts) == 1) {
					$node = $xml->createElement ((string) $key);
				} else {
					$node = $xml->createElement ($aKParts[0]);
					
					$aParamsBin = explode (',', $aKParts[1]);
					foreach ($aParamsBin as $paramBin) {
						$xxx = explode ('=', $paramBin);
						if (isset ($xxx[1])) {
							$node->setAttribute ($xxx[0], $xxx[1]);
						}
					}
				}
				
				if (is_array ($value)) {
					$this->renderData ($xml, $node, $value);
					$parentNode->appendChild ($node);
				} else {
					$value = str_replace ('&', '&amp;', $value);
					$node->nodeValue = (string) $value;
					$parentNode->appendChild ($node);
				}
			}
		}
	}
	
}